package com.seafood.service.impl;

import com.seafood.common.PageResult;
import com.seafood.dto.ProductDTO;
import com.seafood.dto.ProductSearchDTO;
import com.seafood.entity.Category;
import com.seafood.entity.Product;
import com.seafood.repository.CategoryRepository;
import com.seafood.repository.ProductRepository;
import com.seafood.service.ProductService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 产品服务实现类
 */
@Service
@RequiredArgsConstructor
@Transactional
public class ProductServiceImpl implements ProductService {
    
    private final ProductRepository productRepository;
    private final CategoryRepository categoryRepository;
    
    @Override
    public ProductDTO createProduct(ProductDTO productDTO) {
        Product product = convertToEntity(productDTO);
        product.setStatus(Product.ProductStatus.ACTIVE);
        
        Product savedProduct = productRepository.save(product);
        return convertToDTO(savedProduct);
    }
    
    @Override
    public ProductDTO updateProduct(Long id, ProductDTO productDTO) {
        Product product = productRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("产品不存在"));
        
        // 更新字段
        product.setName(productDTO.getName());
        product.setDescription(productDTO.getDescription());
        product.setOrigin(productDTO.getOrigin());
        product.setSpecies(productDTO.getSpecies());
        product.setProcessingMethod(productDTO.getProcessingMethod());
        product.setGrade(productDTO.getGrade());
        product.setPrice(productDTO.getPrice());
        product.setStockQuantity(productDTO.getStockQuantity());
        product.setUnit(productDTO.getUnit());
        product.setWeightPerUnit(productDTO.getWeightPerUnit());
        product.setImageUrl(productDTO.getImageUrl());
        
        if (productDTO.getCategoryId() != null) {
            Category category = categoryRepository.findById(productDTO.getCategoryId())
                    .orElseThrow(() -> new RuntimeException("分类不存在"));
            product.setCategory(category);
        }
        
        if (productDTO.getStatus() != null) {
            product.setStatus(Product.ProductStatus.valueOf(productDTO.getStatus()));
        }
        
        Product savedProduct = productRepository.save(product);
        return convertToDTO(savedProduct);
    }
    
    @Override
    public void deleteProduct(Long id) {
        Product product = productRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("产品不存在"));
        
        // 软删除：更改状态为INACTIVE
        product.setStatus(Product.ProductStatus.INACTIVE);
        productRepository.save(product);
    }
    
    @Override
    @Transactional(readOnly = true)
    public ProductDTO getProductById(Long id) {
        Product product = productRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("产品不存在"));
        return convertToDTO(product);
    }
    
    @Override
    @Transactional(readOnly = true)
    public PageResult<ProductDTO> getProducts(Integer page, Integer size) {
        Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"));
        Page<Product> productPage = productRepository.findByStatus(Product.ProductStatus.ACTIVE, pageable);
        
        return convertToPageResult(productPage);
    }
    
    @Override
    @Transactional(readOnly = true)
    public PageResult<ProductDTO> getProductsByCategory(Long categoryId, Integer page, Integer size) {
        Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"));
        Page<Product> productPage = productRepository.findByCategoryIdAndStatus(
                categoryId, Product.ProductStatus.ACTIVE, pageable);
        
        return convertToPageResult(productPage);
    }
    
    @Override
    @Transactional(readOnly = true)
    public PageResult<ProductDTO> searchProducts(ProductSearchDTO searchDTO) {
        // 构建排序
        Sort.Direction direction = "asc".equalsIgnoreCase(searchDTO.getSortDirection()) 
                ? Sort.Direction.ASC : Sort.Direction.DESC;
        Sort sort = Sort.by(direction, searchDTO.getSortBy());
        Pageable pageable = PageRequest.of(searchDTO.getPage(), searchDTO.getSize(), sort);
        
        // 复合条件查询
        Page<Product> productPage = productRepository.findByMultipleConditions(
                searchDTO.getCategoryId(),
                searchDTO.getKeyword(),
                searchDTO.getOrigin(),
                searchDTO.getMinPrice(),
                searchDTO.getMaxPrice(),
                Product.ProductStatus.ACTIVE,
                pageable
        );
        
        return convertToPageResult(productPage);
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<ProductDTO> getHotProducts(Integer limit) {
        Pageable pageable = PageRequest.of(0, limit);
        List<Product> products = productRepository.findHotProducts(Product.ProductStatus.ACTIVE, pageable);
        
        return products.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<ProductDTO> getRecommendedProducts(Integer limit) {
        Pageable pageable = PageRequest.of(0, limit);
        List<Product> products = productRepository.findRecommendedProducts(Product.ProductStatus.ACTIVE, pageable);
        
        return products.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<ProductDTO> getLowStockProducts(Integer threshold) {
        List<Product> products = productRepository.findLowStockProducts(threshold, Product.ProductStatus.ACTIVE);
        
        return products.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    @Override
    public void updateProductStock(Long productId, Integer quantity) {
        Product product = productRepository.findById(productId)
                .orElseThrow(() -> new RuntimeException("产品不存在"));
        
        product.setStockQuantity(quantity);
        
        // 根据库存更新状态
        if (quantity <= 0) {
            product.setStatus(Product.ProductStatus.OUT_OF_STOCK);
        } else if (product.getStatus() == Product.ProductStatus.OUT_OF_STOCK) {
            product.setStatus(Product.ProductStatus.ACTIVE);
        }
        
        productRepository.save(product);
    }
    
    @Override
    public void reduceProductStock(Long productId, Integer quantity) {
        Product product = productRepository.findById(productId)
                .orElseThrow(() -> new RuntimeException("产品不存在"));
        
        if (product.getStockQuantity() < quantity) {
            throw new RuntimeException("库存不足");
        }
        
        updateProductStock(productId, product.getStockQuantity() - quantity);
    }
    
    @Override
    public void increaseProductStock(Long productId, Integer quantity) {
        Product product = productRepository.findById(productId)
                .orElseThrow(() -> new RuntimeException("产品不存在"));
        
        updateProductStock(productId, product.getStockQuantity() + quantity);
    }
    
    @Override
    public ProductDTO convertToDTO(Product product) {
        ProductDTO dto = new ProductDTO();
        dto.setId(product.getId());
        dto.setName(product.getName());
        dto.setDescription(product.getDescription());
        dto.setOrigin(product.getOrigin());
        dto.setSpecies(product.getSpecies());
        dto.setProcessingMethod(product.getProcessingMethod());
        dto.setGrade(product.getGrade());
        dto.setPrice(product.getPrice());
        dto.setStockQuantity(product.getStockQuantity());
        dto.setUnit(product.getUnit());
        dto.setWeightPerUnit(product.getWeightPerUnit());
        dto.setImageUrl(product.getImageUrl());
        dto.setStatus(product.getStatus().name());
        dto.setInStock(product.getStockQuantity() > 0);
        
        if (product.getCategory() != null) {
            dto.setCategoryId(product.getCategory().getId());
            dto.setCategoryName(product.getCategory().getName());
        }
        
        if (product.getCreatedAt() != null) {
            dto.setCreatedAt(product.getCreatedAt().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        }
        
        if (product.getUpdatedAt() != null) {
            dto.setUpdatedAt(product.getUpdatedAt().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        }
        
        // 解析多图URL
        if (product.getImages() != null && !product.getImages().isEmpty()) {
            try {
                String[] urls = product.getImages().split(",");
                dto.setImageUrls(Arrays.asList(urls));
            } catch (Exception e) {
                dto.setImageUrls(List.of());
            }
        }
        
        return dto;
    }
    
    @Override
    public Product convertToEntity(ProductDTO productDTO) {
        Product product = new Product();
        product.setName(productDTO.getName());
        product.setDescription(productDTO.getDescription());
        product.setOrigin(productDTO.getOrigin());
        product.setSpecies(productDTO.getSpecies());
        product.setProcessingMethod(productDTO.getProcessingMethod());
        product.setGrade(productDTO.getGrade());
        product.setPrice(productDTO.getPrice());
        product.setStockQuantity(productDTO.getStockQuantity() != null ? productDTO.getStockQuantity() : 0);
        product.setUnit(productDTO.getUnit());
        product.setWeightPerUnit(productDTO.getWeightPerUnit());
        product.setImageUrl(productDTO.getImageUrl());
        
        // 处理多图URL
        if (productDTO.getImageUrls() != null && !productDTO.getImageUrls().isEmpty()) {
            product.setImages(String.join(",", productDTO.getImageUrls()));
        }
        
        return product;
    }
    
    /**
     * 转换分页结果
     */
    private PageResult<ProductDTO> convertToPageResult(Page<Product> productPage) {
        List<ProductDTO> content = productPage.getContent().stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
        
        return PageResult.of(
                content,
                productPage.getTotalElements(),
                productPage.getTotalPages(),
                productPage.getNumber(),
                productPage.getSize(),
                productPage.isFirst(),
                productPage.isLast()
        );
    }
}